import { Transform, Type } from 'class-transformer';
import {
  IsEnum,
  IsNotEmpty,
  IsOptional,
  IsString,
  ValidateNested,
} from 'class-validator';

import { IndexQuery } from '../../types';
import { IndexSortDto } from './index-sort.dto';

type QueryExp = NonNullable<IndexQuery['exps']>[number];
const operate: QueryExp['operate'][] = ['BTW', 'LIKE', 'IN', 'EQ'];
const lr: QueryExp['lr'][] = ['and', 'or'];

class QueryExpDto<T extends string = string> {
  @Transform(({ value }) => {
    if (typeof value === 'string' && value.trim() !== '') {
      return value.toUpperCase();
    }
    return value;
  })
  operate: QueryExp['operate'];

  value: any;

  @IsNotEmpty()
  @IsString()
  prop: T;

  @Transform(({ value }) => {
    if (typeof value === 'string' && value.trim() !== '') {
      return value.toLowerCase();
    }
    return value;
  })
  lr?: QueryExp['lr'] = 'and';
}

class QueryItemDto<T extends string = string> {
  @ValidateNested()
  @Type(() => QueryExpDto)
  exps?: QueryExpDto<T>[];
}

export class IndexQueryDto<T extends string = string> extends IndexSortDto<T> {
  @ValidateNested()
  @IsOptional()
  @Type(() => QueryItemDto)
  query?: QueryItemDto<T>[];
}
